﻿using DFGK_WMS.IRepository;
using DFGK_WMS.Model.DTO;
using DFGK_WMS.Model.Models;
using DFGK_WMS.WebAPI.Controllers.Result;
using DFGK_WMS.WebAPI.Tools;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System.Drawing.Printing;
using System.Net.NetworkInformation;

namespace DFGK_WMS.WebAPI.Controllers.库存管理
{
    /// <summary>
    /// 库存查询
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class InventoryQueryController : ControllerBase
    {
        private readonly IOwnerRepository ownerRy;
        private readonly ITWarehouseRepository tWarehouseRy;
        private readonly ITInventoryRepository tInventoryRy;
        private readonly ITDictItemRepository tDictItem;
        private readonly ITDictTypeRepository tDictType;

        public InventoryQueryController(IOwnerRepository ownerRy,ITWarehouseRepository tWarehouseRy,ITInventoryRepository tInventoryRy,ITDictItemRepository tDictItem,ITDictTypeRepository tDictType)
        {
            this.ownerRy = ownerRy;
            this.tWarehouseRy = tWarehouseRy;
            this.tInventoryRy = tInventoryRy;
            this.tDictItem = tDictItem;
            this.tDictType = tDictType;
        }
        /// <summary>
        /// 货主下拉框
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetOwner() 
        {
            try
            {
                var res = ownerRy.GetAll().AsNoTracking().Select(s => new { s.Name, s.Code, s.Id });
                return Ok(BaseResult.Result(res, "200"));
            }
            catch (Exception)
            {
                return Ok(BaseResult.Result(false, "系统错误", "500"));
            }

        }
        /// <summary>
        /// 仓库下拉框
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetWarehouse()
        {
            try
            {
                var res = tWarehouseRy.GetAll().AsNoTracking().Select(s => new { s.Name, s.Code, s.Id });
                return Ok(BaseResult.Result(res, "200"));
            }
            catch (Exception)
            {
                return Ok(BaseResult.Result(false,"系统错误","500"));
            }
        }
        /// <summary>
        /// 批次汇总
        /// </summary>
        /// <param name="owerId"></param>
        /// <param name="whId"></param>
        /// <param name="wlName"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetTInventoryBatchNo(int? whId, string? wlName, int pageIndex = 1, int pageSize = 10)
        {
            if (pageIndex <= 0 || pageSize <= 0)
            {
                return Ok(BaseResult.Result("400", "分页条件有误！"));
            }
            try
            {
                var res = tInventoryRy.GetTInventoryBatchNo(out var totalCount,out var totalQty,out decimal totalTotalWeight, owerId:null, whId, wlName, pageIndex, pageSize);
                return Ok(BaseResult.Result(new { res, totalQty, totalTotalWeight }, "200", totalCount));
            }
            catch (Exception ex)
            {
                return Ok(BaseResult.Result("500", ex.Message));
            }
        }
        /// <summary>
        /// 批次汇总导出
        /// </summary>
        /// <param name="owerId"></param>
        /// <param name="whId"></param>
        /// <param name="wlName"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult InventoryBatchNoExcel(int? owerId, int? whId, string? wlName)
        {
            var res = tInventoryRy.GetTInventoryBatchNo(out var totalCount, out var totalQty, out decimal totalTotalWeight, owerId, whId, wlName, 1, int.MaxValue);
            var excelFile = Utils.ExportToExcel(res, new Dictionary<string, string>()
            {
                { "MaterialCode","物料代码" },
                { "MaterialName","物料名称"},
                { "BatchNo","批次号" },
                { "AvailableQty","数量"},
                { "TotalWeight","重量"}
            });
            return File(excelFile, System.Net.Mime.MediaTypeNames.Application.Octet, "批次汇总.xlsx");
        }
        /// <summary>
        /// 库存汇总
        /// </summary>
        /// <param name="owerId"></param>
        /// <param name="whId"></param>
        /// <param name="wlName"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetTInventoryPage(int? owerId, int? whId, string? wlName, int pageIndex = 1, int pageSize = 10)
        {
            if (pageIndex <= 0 || pageSize <= 0)
            {
                return Ok(BaseResult.Result("400", "分页条件有误！"));
            }
            try
            {
                var res = tInventoryRy.GetTInventoryPage(out var totalCount, out var totalQty, out decimal totalTotalWeight, owerId,whId,wlName,pageIndex,pageSize);
                return Ok(BaseResult.Result(new { res,totalQty,totalTotalWeight },"200",totalCount));
            }
            catch (Exception ex)
            {
                return Ok(BaseResult.Result("500", ex.Message));
            }
        }
     
        /// <summary>
        /// 库存明细
        /// </summary>
        /// <param name="owerId"></param>
        /// <param name="whId"></param>
        /// <param name="wlName"></param>
        /// <param name="kcState"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetTInventoryDtoPage(int? owerId, int? whId, string? wlName, int? kcState, int pageIndex = 1, int pageSize = 10)
        {
            if (pageIndex <= 0 || pageSize <= 0)
            {
                return Ok(BaseResult.Result("400", "分页条件有误！"));
            }
            try
            {
                var res = tInventoryRy.GetTInventoryDtoPage(out var totalCount, owerId, whId, wlName, kcState,pageIndex, pageSize);
                return Ok(BaseResult.Result(res, "200", totalCount));
            }
            catch (Exception ex)
            {
                return Ok(BaseResult.Result("500", ex.Message));
            }
        }
        MemoryStream ProcessExcelData(int? owerId, int? whId, string? wlName)
        {
            //模块从表中读取的数据
            List<TInventory> list = new List<TInventory>();
            list = tInventoryRy.GetTInventoryExcel(owerId,whId,wlName);
            // 已经读取出了正确的数据后
            //创建Excel对象把数据赋值到对象中
            IWorkbook workbook = new XSSFWorkbook(); // Excel对象
            ISheet sheet1 = workbook.CreateSheet("库存汇总");  // 创建Excel中的表对象
                                                           //表头
            IRow row0 = sheet1.CreateRow(0);  // 在sheet1表格中创建第0行
            row0.CreateCell(0).SetCellValue("物料名称"); // 在sheet1表格中第0行创建第0列，并且在给这个单元格赋值
            row0.CreateCell(1).SetCellValue("物料号");
            row0.CreateCell(2).SetCellValue("货主");
            row0.CreateCell(3).SetCellValue("数量");
            row0.CreateCell(4).SetCellValue("总价");
            var rowIndex = 1;
            foreach (var item in list)
            {
                IRow row = sheet1.CreateRow(rowIndex);
                row.CreateCell(0).SetCellValue(item.MaterialName);
                row.CreateCell(1).SetCellValue(item.MaterialCode);
                row.CreateCell(2).SetCellValue(item.OwnerName);
                row.CreateCell(3).SetCellValue(item.AvailableQty.ToString() ?? "NULL");
                row.CreateCell(4).SetCellValue(item.TotalPrice.ToString() ?? "NULL");
                rowIndex++;
            }
            MemoryStream ms = new MemoryStream();
            workbook.Write(ms);

            return ms;
        }
        /// <summary>
        /// 导出库存汇总
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public FileContentResult DownTin(int? owerId, int? whId, string? wlName)
        {
 
            var list = tInventoryRy.GetTInventoryPage(out var totalCount, out var totalQty, out decimal totalTotalWeight, owerId, whId, wlName, 1, int.MaxValue);
            var dicType = new Dictionary<string, string>()
            {
                { "MaterialCode","物料代码" },
                { "MaterialName","物料名称"},
                { "AvailableQty","数量"},
                { "TotalWeight","重量"}
            };
            var fileBytes = Utils.ExportToExcel(list, dicType);
            return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, "库存汇总.xlsx"); //关键语句
        }
        MemoryStream ProcessExcel(int? owerId, int? whId, string? wlName)
        {
            //模块从表中读取的数据
            List<TInventory> list = new List<TInventory>();
            list = tInventoryRy.GetTInventoryExcel(owerId,whId,wlName);
            // 已经读取出了正确的数据后
            //创建Excel对象把数据赋值到对象中
            IWorkbook workbook = new XSSFWorkbook(); // Excel对象
            ISheet sheet1 = workbook.CreateSheet("库存明细");  // 创建Excel中的表对象
                                                           //表头
            IRow row0 = sheet1.CreateRow(0);  // 在sheet1表格中创建第0行
            row0.CreateCell(0).SetCellValue("工厂"); // 在sheet1表格中第0行创建第0列，并且在给这个单元格赋值
            row0.CreateCell(1).SetCellValue("垛号");
            row0.CreateCell(2).SetCellValue("物料名称");
            row0.CreateCell(3).SetCellValue("物料号");
            row0.CreateCell(4).SetCellValue("批次号");
            row0.CreateCell(5).SetCellValue("仓位编码");
            row0.CreateCell(6).SetCellValue("仓位名称");
            row0.CreateCell(7).SetCellValue("状态");
            row0.CreateCell(8).SetCellValue("数量");
            var rowIndex = 1;
            foreach (var item in list)
            {
                var Sta = "";//1-正常库存；2-转移中的库存；3-入库在途；4-出库在途；5-限制使用的库存;6-异常库存;7-预分配库存;8-冻结库存
                if (item.Status == 1)
                {
                    Sta = "正常库存";
                }
                if (item.Status == 2)
                {
                    Sta = "转移中的库存";
                }
                if (item.Status == 3)
                {
                    Sta = "入库在途";
                }
                if (item.Status == 4)
                {
                    Sta = "出库在途";
                }
                if (item.Status == 5)
                {
                    Sta = "限制使用的库存";
                }
                if (item.Status == 6)
                {
                    Sta = "异常库存";
                }
                if (item.Status == 7)
                {
                    Sta = "预分配库存";
                }
                if (item.Status == 8)
                {
                    Sta = "冻结库存";
                }
                IRow row = sheet1.CreateRow(rowIndex);
                row.CreateCell(0).SetCellValue(item.ProduceFactory);
                row.CreateCell(1).SetCellValue(item.PalletBarcode);
                row.CreateCell(2).SetCellValue(item.MaterialName);
                row.CreateCell(3).SetCellValue(item.MaterialCode);
                row.CreateCell(4).SetCellValue(item.BatchNo);
                row.CreateCell(5).SetCellValue(item.LocationCode);
                row.CreateCell(6).SetCellValue(item.AreaName);
                row.CreateCell(7).SetCellValue((double)item.Status);
                row.CreateCell(8).SetCellValue(item.AvailableQty.ToString() ?? "NULL");
                rowIndex++;
            }
            MemoryStream ms = new MemoryStream();
            workbook.Write(ms);

            return ms;
        }
        /// <summary>
        /// 导出库存明细
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public FileContentResult DownTinM(int? owerId, int? whId, string? wlName)
        {
            //MemoryStream ms = ProcessExcel(owerId, whId, wlName);
            //byte[] fileBytes = ms.ToArray();
            var res = tInventoryRy.GetTInventoryDtoPage(out var totalCount, owerId, whId, wlName, null, 1, int.MaxValue);
            var fileBytes=Utils.ExportToExcel(res,new Dictionary<string, string>() 
            {
                {"PalletBarcode","托盘条码" },
                {"LocationCode","货位名称" },
                {"MaterialName","物料描述" },
                {"AvailableQty","库存数量"},
                {"WhetherQualified","产品状态" },
                {"MaterialCode","物料代码" },
                {"BatchNo","物料批次"},
            });
            return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, "库存明细.xlsx"); //关键语句
        }
        /// <summary>
        /// 产品状态下拉框
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetArticlebarcode()
        {
            var tyepName = tDictType.GetAll().FirstOrDefault(s=>s.TypeName=="产品状态");
            if (tyepName == null)
            {
                return Ok(BaseResult.Result("500", "找不到产品状态"));
            }
            var dicItem = tDictItem.GetDictItems().Where(s=>s.TypeId==tyepName.Id);
            if (dicItem!=null && dicItem.Any())
            {
                return Ok(BaseResult.Result(dicItem,"200"));
            }
            return Ok(BaseResult.Result("500", "系统错误，找不到产品状态"));
        }
        /// <summary>
        /// 修改库存的产品状态 不想写put了
        /// </summary>
        /// <param name="id">库存id</param>
        /// <param name="itemName">字典类型</param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult UpdArticlebarcode(int id,string itemName)
        {
            var invObj = tInventoryRy.GetAll().FirstOrDefault(s=>s.Id==id);
            if (invObj == null)
            {
                return Ok(BaseResult.Result("500", "系统错误，找不到该库存"));
            }
            invObj.WhetherQualified = itemName;
            if (tInventoryRy.Upd(invObj))
            {
                return Ok(BaseResult.Result("200", "修改成功"));
            }
            return Ok(BaseResult.Result("500", "系统错误，修改失败"));
        }

        /// <summary>
        /// 添加备注
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        [HttpPut]
        public IActionResult UpdateRemark(InventoryRemark m)
        {
            if (m.Id <= 0)
                return Ok(BaseResult.Result("400", "Id有误"));

            bool result = tInventoryRy.UpdateRemark(m);
            if (result)
                return Ok(BaseResult.Result(result, "200", "修改成功！"));
            return Ok(BaseResult.Result(result, "500", "修改失败！"));
        }
    }
}
